package com.guo.redis.business.hello.controller;

import com.guo.redis.business.hello.service.StockCounterService;
import com.guo.redis.config.lock.LockValueContainer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 分布式计数器，模拟减库存 Redis 实现
 * @author gxy
 * @date 2021年6月28日00:00:39
 */
@RestController
@RequestMapping("/stock")
@Slf4j
public class StockController {

    @Resource(name="incrementStockCounterServiceImpl")
    private StockCounterService stockCounterService;

    @Resource(name="distributeLockIncrementStockCounterServiceImpl")
    private StockCounterService distributeLockStockCounterService;


    //剩余库存操作
    @RequestMapping("/leftStock")
    public Object getLeftStockAmount(){
        String stockKey = stockKey();
        return stockCounterService.getStockNumbers(stockKey);
    }

    //减库存操作 本地锁
    @RequestMapping("/countDownStock")
    public Object countDownStock(){
        String stockKey = stockKey();
        long l = stockCounterService.countDownStock(stockKey, 1, key -> {
            stockCounterService.initStock(key, 600, getInitStockAmount(stockKey));
        });
        return l>=0;
    }

    private String stockKey(){
        long stockId = 23;
        return "redis_key:stock:"+stockId;
    }

    //减库存操作2 分布式锁
    @RequestMapping("/countDownStock2")
    public Object countDownStock2(){
        long stockId = 232;
        String stockKey = "redis_key:stock:"+stockId;
        int i = ThreadLocalRandom.current().nextInt(10);
        String value = ""+Thread.currentThread().getId()+i;
        try {
            LockValueContainer.getInstance().saveValue(value);
            long l = distributeLockStockCounterService.countDownStock(stockKey, 1, key -> {
                distributeLockStockCounterService.initStock(key, 600, getInitStockAmount(stockKey));
            });
            return l>=0;
        }finally {
            LockValueContainer.getInstance().remove();
        }
    }

    private long getInitStockAmount(String stockKey){
        return 100;
    }

}
